package com.sunny.example.string;

import java.util.Scanner;
import java.util.Stack;

public class HJ50_四则运算 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String express = scanner.nextLine();

            //1、将中缀表达转为后缀表达式
            String prexExp = toPrexExp(express);
            //2、利用后缀表达式进行计算
            int result = caculate(prexExp);
            System.out.println(result);
        }
    }

    /**
     * 利用后缀表达式进行计算
     * <p>
     * 利用一个Stack来存储数字
     *
     * @param express
     */
    private static int caculate(String express) {
        Stack<Integer> numStack = new Stack<>();
        Integer result = 0;
        String[] strs = express.split(" ");
        for (int i = 0; i < strs.length; i++) {
            String c = strs[i];
            if (c.matches("-?\\d+")) {
                numStack.push(Integer.valueOf(c));
            } else {
                Integer i1 = numStack.pop();
                Integer i2 = numStack.pop();
                switch (c) {
                    case "+":
                        result = i1 + i2;
                        numStack.push(result);
                        break;
                    case "-":
                        result = i2 - i1;
                        numStack.push(result);
                        break;
                    case "*":
                        result = i2 * i1;
                        numStack.push(result);
                        break;
                    case "/":
                        result = i2 / i1;
                        numStack.push(result);
                        break;

                }
            }
        }
        if (numStack.size() > 1) {
            return numStack.pop() + numStack.pop();
        }
        return numStack.pop();

    }

    /**
     * 中缀表达转后缀表达式
     *
     * @param express
     * @return
     */
    private static String toPrexExp(String express) {
        Stack<String> op = new Stack<>();//用于存储操作数
        String prexExp = "";
        for (int i = 0; i < express.length(); i++) {
            char c = express.charAt(i);
            if (Character.isDigit(c)) {//这里有个问题。对于2位及以上的数字未处理。
                //是数字
                prexExp = prexExp + c + " ";
            } else {
                //字符
                String opStr = String.valueOf(c);
                switch (opStr) {
                    case "(":
                    case "[":
                    case "{":
                    case "*":
                    case "/":
                        op.push(opStr);
                        break;
                    //如果是+ - * /，则需要判断栈顶的操作符与当前操作符的优先级
                    case "+":
                    case "-":
                        //当为“-”号时，有可能也是负数，
                        if (opStr.equals("-") && (i == 0 || i >= 1 && !Character.isDigit(express.charAt(i - 1)))) {
                            //当前面不是数字，或者为首位时为负数
                            prexExp += opStr;
                            break;
                        }
                        while (!op.isEmpty() && !op.peek().equals("(") && !op.peek().equals("[") && !op.peek().equals("{")) {
                            prexExp += op.peek() + " ";
                            op.pop();
                        }
                        op.push(opStr);
                        break;
                    case ")":
                        while (!op.peek().equals("(")) {
                            prexExp += op.peek() + " ";
                            op.pop();
                        }
                        op.pop();//将左括号弹出；
                        break;
                    case "]":
                        while (!op.peek().equals("[")) {
                            prexExp += op.peek() + " ";
                            op.pop();
                        }
                        op.pop();//将左括号弹出；
                        break;
                    case "}":
                        //弹出栈
                        while (!op.peek().equals("{")) {
                            prexExp += op.peek() + " ";
                            op.pop();
                        }
                        op.pop();//将左括号弹出；
                        break;
                }
            }
        }
        if (!op.isEmpty()) {
            prexExp += op.pop();
        }
        return prexExp;
    }
}
